package cn.amebius.simpledocker.service.impl;

import cn.amebius.simpledocker.controller.request.AddUserRequest;
import cn.amebius.simpledocker.entity.dto.UserGroupInfoDto;
import cn.amebius.simpledocker.entity.dto.UserPageDto;
import cn.amebius.simpledocker.entity.dto.UserRoleInfoDto;
import cn.amebius.simpledocker.entity.model.PageModel;
import cn.amebius.simpledocker.entity.po.*;
import cn.amebius.simpledocker.entity.dto.UserBaseInfoDto;
import cn.amebius.simpledocker.exception.DataErrorException;
import cn.amebius.simpledocker.mapper.GroupMapper;
import cn.amebius.simpledocker.mapper.PermissionMapper;
import cn.amebius.simpledocker.mapper.RoleMapper;
import cn.amebius.simpledocker.mapper.UserMapper;
import cn.amebius.simpledocker.service.UserService;
import cn.amebius.simpledocker.util.PageRequest;
import cn.hutool.core.date.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 用户服务实现类
 * @author 阿伟
 * @date 2023/7/28 15:49
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    GroupMapper groupMapper;

    @Autowired
    PermissionMapper permissionMapper;


    @Override
    public UserBaseInfoDto getBaseInfo(Integer userId) {
        UserBaseInfoDto ubid = userMapper.selectInfoById(userId);
        UserBaseInfoDto.check(ubid);
        return ubid;
    }

    @Override
    public UserRoleInfoDto getUserRole(Integer userId) {
        UserRoleRelationPo urrp = userMapper.selectUserRoleByUserId(userId);
        UserRoleRelationPo.check(urrp);
        Integer roleId = urrp.getRoleId();
        RolePo rp = roleMapper.selectById(roleId);
        UserRoleInfoDto urid = new UserRoleInfoDto();
        urid.setName(rp.getName());
        urid.setDescription(rp.getDescription());
        urid.setCreateTime(rp.getCreateTime());
        urid.setDesignation(rp.getDesignation());
        urid.setRoleId(rp.getId());
        return urid;
    }

    @Override
    public UserGroupInfoDto getUserGroup(Integer userId) {
        UserGroupRelationPo userGroupRelationPo = userMapper.selectUserGroupByUserId(userId);
        if (userGroupRelationPo == null) {
            throw new DataErrorException("数据异常:用户小组丢失");
        }
        Integer groupId = userGroupRelationPo.getGroupId();
        GroupPo gp = groupMapper.selectById(groupId);
        UserGroupInfoDto ugid = new UserGroupInfoDto();
        ugid.setCreateTime(gp.getCreateTime());
        ugid.setDescription(gp.getDescription());
        ugid.setName(gp.getName());
        ugid.setGroupId(gp.getId());
        return ugid;
    }

    @Override
    public Set<String> getUserPermission(Integer userId) {
        UserRoleRelationPo urrp = userMapper.selectUserRoleByUserId(userId);
        UserRoleRelationPo.check(urrp);
        Integer roleId = urrp.getRoleId();
        Set<RolePermissionRelationPo> rprps = roleMapper.selectRolePermission(roleId);
        //角色无权限不会报错
        Set<String> retSet = new HashSet<>();
        for (RolePermissionRelationPo rprp : rprps) {
            Integer permissionId = rprp.getPermissionId();
            PermissionPo pp = permissionMapper.selectById(permissionId);
            PermissionPo.check(pp);
            retSet.add(pp.getName());
        }
        return retSet;
    }

    @Override
    public PageModel<UserPageDto> getUserPage(PageRequest pr) {
        PageModel<UserPageDto> pm = new PageModel<>();
        List<UserPo> userList;
        List<UserPageDto> userPageList = new ArrayList<>();
        pm.setPageSize(pr.getPageSize());
        pm.setPageNum(pr.getPageNum());
        Integer start = 0;
        Integer size = pr.getPageSize();
        Integer counts = 0;
        if (pr.getPageNum()!= 0) {
            start = (pr.getPageNum() - 1) * pr.getPageSize();
        }
        if (pr.getKeyWords().isEmpty()) {
            userList = userMapper.listByLimit(start, size);
            counts = userMapper.count();
        } else {
            userList = userMapper.listByLimitLikeKeyWords(pr.getKeyWords(), start, size);
            counts = userMapper.countByLikeKeyWords(pr.getKeyWords());
        }
        if (userList == null) {
            throw new DataErrorException("数据异常:用户分页丢失");
        }
        pm.setCount(counts);
        for (UserPo up : userList) {
            UserPo.check(up);
            UserPageDto upd = new UserPageDto();
            upd.setName(up.getName());
            upd.setStatus(up.getDeleted());
            upd.setCreateTime(up.getCreateTime());
            upd.setUsername(up.getUsername());
            upd.setEmail(up.getEmail());
            upd.setMobile(up.getMobile());
            Integer userId = up.getId();
            upd.setId(userId);
            UserRoleRelationPo urrp = userMapper.selectUserRoleByUserId(userId);
            UserRoleRelationPo.check(urrp);
            RolePo rp = roleMapper.selectById(urrp.getRoleId());
            RolePo.check(rp);
            upd.setUserRole(rp.getName());
            UserGroupRelationPo ugrp = userMapper.selectUserGroupByUserId(userId);
            UserGroupRelationPo.check(ugrp);
            GroupPo gp = groupMapper.selectById(ugrp.getGroupId());
            GroupPo.check(gp);
            upd.setGroupName(gp.getName());
            userPageList.add(upd);
        }
        pm.setCards(userPageList);
        return pm;
    }


    @Transactional
    @Override
    public void addUser(AddUserRequest aur) {
        DateTime createTime = DateTime.now();
        try {
            userMapper.insertUser(aur,createTime);
        } catch (Exception e) {
            throw new DataErrorException("数据异常: 账号已经存在或用户添加错误");
        }
        Integer userId;
        try {
            UserPo up = userMapper.selectByUsername(aur.getUsername());
            userId = up.getId();
            userMapper.insertUserAndGroup(userId,aur.getGroupId(),createTime);
        } catch (Exception e) {
            throw new DataErrorException("数据异常: 用户小组添加失败");
        }
        try {
            userMapper.insertUserAndRole(userId,aur.getRoleId(),createTime);
        } catch (Exception e) {
            throw new DataErrorException("数据异常: 用户角色添加失败");
        }
    }

}
